package de.fhhof.robot.control.impl;

import de.fhhof.robot.control.ApplicationStorage;
import de.fhhof.robot.control.Color;
import de.fhhof.robot.control.ConnectionFactory;
import de.fhhof.robot.control.IControlToStorage;
import de.fhhof.robot.control.IMessage;
import de.fhhof.robot.control.Message;
import de.fhhof.robot.control.cmd.concreate.AssemblyState;
import de.fhhof.robot.control.cmd.concreate.MessageState;
import de.fhhof.robot.control.common.CommandConstants;
import de.fhhof.robot.control.common.CommonConstants;
import de.fhhof.robot.control.common.MessageUtility;
import de.fhhof.robot.control.common.Utility;
import de.fhhof.robot.control.net.IConnection;

public class ControlToStorage implements IControlToStorage {


    private static IConnection storageConnection = null;
   
    public static IConnection getStorageConnection(){
        if(storageConnection == null){
        	storageConnection = ConnectionFactory.getConnection(CommonConstants.STORAGE_PORT ,CommonConstants.CONTROL, CommonConstants.STORAGE);
        }
       
        return storageConnection;
    }
   
    public IMessage getSmartiesStatus(IMessage msg) {
        //TODO
        /** step 1
         * send message to storage to get the no of smarties for each color
         * msg: STSlK001 , 5 times
         * and count from return msg.
         * example: red color
         * loop 5 times the following process
         * send this message to storage : STSlK001<MSG ID>0001r
         * return msg from storage : SlSTA002<msg id>000288
         * Red = 88
         * no of smarties = sum ( all colors)
         */
        String replymsgfromsl =null;
        IConnection conStorage = getStorageConnection();
        /////////////////////////for all colors//////////////////////////
        int col[] =new int []{0,0,0,0,0};
        int i=0;
       
        String payLoad  = "";
        System.out.println("Enquiring smaties for all color: ");
        for(Color color: Color.values())
        {
                System.out.print(" "+ color.getCode());
                String colorcode = color.getCode()+ "";
                IMessage msgST = new Message(CommandConstants.CMD_ST_SL_REQUEST_AMOUNT_SPECIFIC_COLOR_K001,colorcode);
                conStorage.send(msgST);
                IMessage ack1 = conStorage.receive();
                if(ack1.getCommand().startsWith("F"))
                {
                    System.out.println("Received error response from storage..."+ ack1.getCommand());
                    IMessage msgError = new Message("F000","");
                    return msgError;
                }
                if(ack1.getCommand().equals("A002"))
                {
                	System.out.println();
                    System.out.println("Invalid response from storage ack1: "+ ack1.getCommand());
                    IMessage msgError = new Message("F999","");
                    return msgError;
                }
                if(ack1.getCommand().startsWith("A") && ack1.getCommand().endsWith("1"))
                {
                    IMessage ack2 = conStorage.receive();
                    replymsgfromsl = ack2.getPayload();
                    if(ack2.getCommand().startsWith("F"))
                    {
                        System.out.println("Invalid response from storage ack2: "+ ack2.getCommand() +" during calculating smarties for color : " + color.name());
                        col[i] = 0;
                        replymsgfromsl = 0+"";
                    }
                     
                     try
                     {
                         col[i]= Integer.parseInt(replymsgfromsl);
                     }
                     catch(NumberFormatException ex)
                     {
                         IMessage msgError = new Message("F999","");
                         return msgError;
                     }
                }       
                payLoad += color.getCode() +Utility.leftPad(col[i]+"","0",3);
                i++;
            replymsgfromsl = null;
        }
        IMessage msgReply = new Message("A005",payLoad);
        return msgReply;
    }

    @Override
    public boolean isValidPatternToConstruct(IMessage msg,AssemblyState assemblyState)
    {
   
        boolean isValid = true;
        int col[] =new int []{0,0,0,0,0};
         
        col[0] = MessageUtility.getRequiredColor(Color.RED, msg.getPayload());
        col[3] = MessageUtility.getRequiredColor(Color.BLUE, msg.getPayload());
        col[1] = MessageUtility.getRequiredColor(Color.GREEN, msg.getPayload());
        col[2] = MessageUtility.getRequiredColor(Color.YELLOW, msg.getPayload());
        col[4] = MessageUtility.getRequiredColor(Color.BROWN, msg.getPayload());
       
        IConnection conStorage = getStorageConnection();
        int i=0;
        for(Color color: Color.values()){
            //System.out.println(color.getCode() + " - "+ col[i]);
        	if(i < assemblyState.getLastColor()){
        		i++;
        		continue;
        	}
            if(col[i] > 0){
                String payLoad = color.getCode()+""+ Utility.pad(col[i]+"", 3);
                IMessage msgST = new Message("K002",payLoad);
                
                if(!assemblyState.getMsgSmartiesAvState().isSent()){
                	conStorage.send(msgST);
                	assemblyState.getMsgSmartiesAvState().setSent(true);
                	assemblyState.setLastColor(i);
                	ApplicationStorage.getAssemblyState().store(assemblyState, CommonConstants.STORAGE_FILE_NAME);
                }
                IMessage ack1 = null;
                if(!assemblyState.getMsgSmartiesAvState().isAck1Received()){
                    ack1 = conStorage.receive();
                    if(ack1 == null ){
                    	System.out.println("Expected ack1 but got null");
                    	return false;
                    }
                    if(!ack1.getCommand().equals("A001")){
                    	System.out.println("Expected ack1: A001 but got "+ ack1.getCommand());
                    	return false;
                    }                    
                	assemblyState.getMsgSmartiesAvState().setAck1Received(true);
                	assemblyState.getMsgSmartiesAvState().setAck1(ack1);
                	
                	ApplicationStorage.getAssemblyState().store(assemblyState, CommonConstants.STORAGE_FILE_NAME);
                }else{
                	ack1 = assemblyState.getMsgSmartiesAvState().getAck1();
                }
                
                IMessage ack2 = null;
                if(!assemblyState.getMsgSmartiesAvState().isAck2Received()){
                    ack2 = conStorage.receive();
                    if(ack2 == null ){
                    	System.out.println("Expected ack2 but got null");
                    	return false;
                    }
                    if(!ack2.getCommand().equals("A002")){
                    	System.out.println("Expected ack2: A002 but got "+ ack2.getCommand());
                    	return false;
                    }                    
                	assemblyState.getMsgSmartiesAvState().setAck2Received(true);
                	assemblyState.getMsgSmartiesAvState().setAck2(ack2);
                	
                	ApplicationStorage.getAssemblyState().store(assemblyState, CommonConstants.STORAGE_FILE_NAME);                    
                }
                else{
                	ack2 = assemblyState.getMsgSmartiesAvState().getAck2();
                }

                if(ack1.getCommand().startsWith("F") || (ack2 != null && ack2.getCommand().startsWith("F"))){
                    isValid = false;
                    break;
                }
                //System.out.println("Color: "+ color.getCode() + " :"+ ack2.getPayload());
                assemblyState.setMsgSmartiesAvState(new MessageState());
                ApplicationStorage.getAssemblyState().store(assemblyState, CommonConstants.STORAGE_FILE_NAME); 
            }
            i++;
        }
        assemblyState.setLastColor(0);
        ApplicationStorage.getAssemblyState().store(assemblyState, CommonConstants.STORAGE_FILE_NAME);
        return isValid;

    }
	private IMessage sendMessage(IMessage msg,IConnection conn,MessageState state, AssemblyState assemblyState){
		return Utility.sendMessage(msg, conn, state, assemblyState);
	}
   
}